Vue3 Composition API的文章寫到了Component的階段,想要來整理一下前面的進度,來製作一個綜合的案例,這個案例的規劃如下:
了解程式碼之前,可以先看看已經完成的範例檔
外部json檔
{
"system": [
{ "id":0, "title":"請選擇手機系統", "value": "", "disabled": true, "default": true },
{ "id":1, "title":"Android", "value": "Android" },
{ "id":2, "title":"iOS", "value": "iOS" }
],
"provider": [
{ "id":0, "title":"請選擇電信業者", "value": "", "disabled": true, "default": true },
{ "id":1, "title":"中華電信", "value": "CHT" },
{ "id":2, "title":"台灣大哥大", "value": "TWN" },
{ "id":3, "title":"遠傳", "value": "FET" }
],
}
程式碼的部分
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Vue Component</title>
<link href="vueComponent.css" rel="stylesheet" type="text/css">
<script src="https://unpkg.com/vue@next"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/axios/0.19.2/axios.min.js"></script>
<style>
.wrapper {
display: flex;
width: 700px;
margin: auto;
}
.wrapper .selectDiv {
width: 300px;
height: 270px;
border: black 1px solid;
margin: 10px auto 20px auto;
}
.wrapper .selectDiv .icon {
text-align: center;
}
.wrapper .selectDiv .icon img {
width: 150px;
margin-bottom: 10px;
}
</style>
</head>
<body>
<div class="wrapper" id="app">
<div class="selectDiv">
<dropdownmenu
:items="state.selectData.system"
@dropdownmenu-change="state.selectedData.system = $event + '.png'">
</dropdownmenu>
<div class="icon">
<img
v-bind:src="'images/' + state.selectedData.system"
v-if="state.selectedData.system !== null">
</div>
</div>
<div class="selectDiv">
<dropdownmenu
:items="state.selectData.provider"
@dropdownmenu-change="state.selectedData.provider = $event + '.png'">
</dropdownmenu>
<div class="icon">
<img
v-bind:src="'images/' + state.selectedData.provider"
v-if="state.selectedData.provider !== null">
</div>
</div>
</div>
</body>
</html>
<script>
const { reactive, onBeforeMount } = Vue;
const app = {
setup(){
const state = reactive({
selectData: {
system: null,
provider: null,
},
selectedData: {
system: null,
provider: null,
}
})
onBeforeMount(() => {
axios.get("vueComponent.json").then((response) => {
state.selectData = response.data;
}).catch(function (response) {
console.log(response);
})
})
return { state }
}
}
const myVue = Vue.createApp(app);
myVue.component("dropdownmenu", {
props: ['items'],
template: `
<div class="section">
<div class="select">
<select :name="items" @change="dataChange">
<option
v-for="item in items"
:value="item.value"
:disabled="item.disabled"
:selected="item.default"
@change="dataChange">
{{ item.title }}</option>
</select>
</div>
</div>
`,
setup(props, target){
function dataChange(){
target.emit('dropdownmenu-change', event.target.value);
}
return{ dataChange }
},
})
myVue.mount("#app");
</script>
透過以上的程式碼來驗證我們的目標項目:
第一點. 製作一個Fancy的下拉式選單:透過CSS來建構出一個Fancy的下拉式選單
第二點. 將這個下拉式選單製作成Vue Component:透過程式碼92~115行完成,設定當使用者更換選單內容時,會發出一個dropdownmenu-change事件,並帶使用者選擇的項目value。
3. 這個下拉式選單的內容(option)來自於外部(json):透過程式碼80~86行完成,利用axios載入json檔至元件。
4. 下拉式選單元件的內容改變後,可以影響到非元件的內容:當元件發出dropdownmenu-change
事件時,將值寫入vue data selectedData對應的項目中,並使用v-bind:src來綁定vue data至圖片標籤。
以上就是今天特意練習之前進度的一個範例,跟大家分享,但這樣的組件設計僅能讓該頁面使用到這個組件,如果要在多個HTML使用同一組件,我們必須先了解webpack和vue-cli的使用,接下來的文章就準備往這個方向介紹,敬請期待囉!